/* @flow */

//该方法用于将relative路径转换为绝对路径，如果relative原本就是绝对路径，则
//直接返回，否则根据base字符串解析获得绝对路径
export function resolvePath(relative: string,
                            base: string,
                            //append的作用是什么？
                            //设置 append 属性后，则在当前（相对）路径前添加基路径。
                            //例如，我们从 /a 导航到一个相对路径 b，如果没有配置 append，则路径为 /b，如果配了，则为 /a/b
                            append?: boolean): string {
    const firstChar = relative.charAt(0)
    //如果是绝对路径，直接返回
    if (firstChar === '/') {
        return relative
    }

    if (firstChar === '?' || firstChar === '#') {
        return base + relative
    }

    const stack = base.split('/')

    // remove trailing segment if:
    // - not appending
    // - appending to trailing slash (last segment is empty)
    // append的作用如上所述，示例：
    // 当前浏览器中的url为：'http://localhost/a'
    // <router-link :to="{ path: 'b'}" append></router-link>
    // 如果使用了append属性，则访问的url为：'http://localhost/a/b
    // 如果未使用append属性，则访问的url为：'http://localhost/b'
    if (!append || !stack[stack.length - 1]) {
        stack.pop()
    }

    // resolve relative path
    // 解析并支持相对路径
    const segments = relative.replace(/^\//, '').split('/')
    for (let i = 0; i < segments.length; i++) {
        const segment = segments[i]
        if (segment === '..') { //跳转到上一级路径
            stack.pop()
        }
        //如果segment不是'.'，则加入stack中，否则直接忽略
        else if (segment !== '.') {
            stack.push(segment)
        }
    }

    // ensure leading slash
    if (stack[0] !== '') {
        stack.unshift('')
    }

    return stack.join('/')
}

//解析path字符串，获得可能存在的查询字符串和hash字符串
export function parsePath(path: string): {
    path: string;
    query: string;
    hash: string;
} {
    let hash = ''
    let query = ''

    const hashIndex = path.indexOf('#')
    if (hashIndex >= 0) {
        hash = path.slice(hashIndex)
        path = path.slice(0, hashIndex)
    }

    const queryIndex = path.indexOf('?')
    if (queryIndex >= 0) {
        query = path.slice(queryIndex + 1)
        path = path.slice(0, queryIndex)
    }

    return {
        path,
        query,
        hash
    }
}

export function cleanPath(path: string): string {
    return path.replace(/\/\//g, '/')
}
